package dabs.engine.plant;

import dabs.engine.control.ComponentCommand;
import dabs.engine.environment.AcceptsModifier;
import dabs.engine.environment.Modifier;
import dabs.engine.environment.TemporaryDisable;
import dabs.engine.messaging.Notification;
import dabs.engine.messaging.NotificationHandler;

public class Valve extends ComponentPart implements AcceptsModifier{
	private static final long serialVersionUID = 1918207822741948764L;
	
	private boolean isOpen;
	private boolean saveIsOpen = true;
	
	public Valve(NotificationHandler mailBox, String name, boolean openState, int capacity, int outRate) {
		super(mailBox, name, capacity, outRate);
		isOpen = openState;
	}

	public boolean getIsOpen() { return isOpen; }
	
	public void setIsOpen(boolean isOpen){ 
		if (isDeactivated() == false){ 
			this.isOpen = isOpen; 
			if (isOpen){
				passMessage(new Notification(getName(), "Opened."));
			}
			else{
				passMessage(new Notification(getName(), "Closed."));
			}
		}
		else { 
			super.passMessage(new Notification(super.getName(), 
					"Valve is blocked."));
		}
	}
	
	@Override
	protected void receiveModifier(Modifier modifier) {
		super.receiveModifier(modifier);
		if (modifier instanceof TemporaryDisable) {
			saveIsOpen = isOpen;
			isOpen = false;
		} else { 
			throw new RuntimeException("wtf is this modifier? " + modifier.getClass().getName());
		}
	}
	
	@Override
	protected void inactivatedModifier(Modifier modifier) {
		super.inactivatedModifier(modifier);
		if (modifier instanceof TemporaryDisable) {
			isOpen = saveIsOpen;
			passMessage(new Notification(getName(), "is now active again"));
		}
	}
	
	@Override
	public void tick() {
		if (isOpen) {
			getNewHydroState().sendToNext(getHydroProp().getOutRate(), true, getOutputs(), getPressure());
			getNewHydroState().sendToNext(getHydroProp().getOutRate(), false, getOutputs(), getPressure());
		}
		super.tick();
	}
	
	@Override
	public void runCommand(ComponentCommand command) {
		assert(command.getDestination().equals(getName()));
		if (command.getArguments().get(0).equals("open")){
			setIsOpen(true);
		}
		else if (command.getArguments().get(0).equals("close")){
			setIsOpen(false);
		}
		else{
			passMessage(new Notification(getName(), "Command must be open or close."));
		}
	}
	
	@Override
	public String read() {
		return String.format("%s\tState: %s\n", super.read(), getIsOpen() ? "opened" : "closed");
	}
	
	
	
}
